package com.rzjm.api.util;

import com.rzjm.api.entity.DeviceRange;
import com.rzjm.api.entity.dto.Cone;

import java.awt.geom.Line2D;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Arrays;

/**
 * @创建者：zhouwei
 * @创建时间：2021/9/29
 * @描述：
 */
public class MathUtil {


	/**
	 * 2个 Int 类型数字 相除 保留2位小数
	 *
	 * @param a
	 * @param b
	 * @return
	 */
	public static double getDoubleByInt(long a, long b) {
		DecimalFormat df = new DecimalFormat("0.00");
		String num = "0.00";
		if (b > 0) {
			float f = (float) a / b;
			num = df.format(f);
		}
		return Double.parseDouble(num);
	}

	/**
	 * 2个 Double 类型数字 相除 保留2位小数
	 *
	 * @param a
	 * @param b
	 * @return
	 */
	public static double getDoubleByD(double a, double b) {
		DecimalFormat df = new DecimalFormat("0.00");
		String num = "0.00";
		if (b > 0) {
			double f = a / b;
			num = df.format(f);
		}
		return Double.parseDouble(num);
	}

	public static double getDoubleUp(double a){
		BigDecimal bg = new BigDecimal(a).setScale(2, RoundingMode.HALF_UP);
		return bg.doubleValue();
	}

	public static double getDoubleUpThree(double a){
		BigDecimal bg = new BigDecimal(a).setScale(3, RoundingMode.HALF_UP);
		return bg.doubleValue();
	}

	public static double getDoubleUpFour(double a){
		BigDecimal bg = new BigDecimal(a).setScale(4, RoundingMode.HALF_UP);
		return bg.doubleValue();
	}

	/**
	 *  对当前小数保留2位
	 *
	 * @param a
	 * @return
	 */
	public static double getDouble(double a) {
		DecimalFormat df = new DecimalFormat("0.00");
		String num = "0.00";
		num = df.format(a);
		return Double.parseDouble(num);
	}

	/**
	 *  a 占 b 的百分比
	 * @param a
	 * @param b
	 * @return
	 */
	public static String getRatio(long a, long b) {
		DecimalFormat df = new DecimalFormat("0.00");
		String num = "0.00";
		if (b > 0) {
			float f = (float) a / b;
			num = df.format(f*100);
		}
		return num;
	}

	public static double getDi(double height,double angle){
		double l = 2 * height * Math.tan(angle / 2);
		return l;
	}

	/**
	 * 直角三角获取斜边
	 * @param a 直角边长
	 * @param b 直角边长
	 * @return 斜边边长
	 */
	public static Double getHypotenuseFromLength(double a,double b){
		return Math.sqrt(a*a+b*b);
	}

	/**
	 * 直角三角形 根据直角边和斜边求直角边
	 * @param right 直角边
	 * @param hypotenuse 斜边
	 * @return 直角边长
	 */
	public static double getRightSideFromLength(double right,double hypotenuse){
		return Math.sqrt(hypotenuse*hypotenuse - right*right);
	}

	/**
	 * 直角三角形 根据角度和直角边长求斜边
	 * @param degree    角度
	 * @param width     直角边长
	 * @return 斜边边长
	 */
	public static double getHypotenuseFromDegree(double degree,double width){
		double cos = Math.cos(Math.toRadians(degree));//余弦
		return width / cos;
	}

	/**
	 * 直角三角形 根据角度和斜边求直角边
	 * @param degree    角度
	 * @param width     斜边
	 * @return 直角边长
	 */
	public static double getRightSideFromDegree(double degree,double width){
		double cos = Math.cos(Math.toRadians(degree));
		return width * cos;
	}


	//Method goes here
	//计算直角三角形第三条边
	public static double hypotenuse(double a, double b){
		return Math.sqrt(Math.pow(a,2) + Math.pow(b, 2));
	}


	//Method goes here
	//计算直角三角形第三条边
	public static double getHorizontalLength(double c, double a){
		return Math.sqrt(Math.pow(c,2) - Math.pow(a, 2));
	}

	/**
	 * 根据 B角和C角的c边长，获取A角-C角的b边长
	 * @param A
	 * @param B
	 * @param c
	 * @return
	 */
	public static double getSideFromSideAndDegree(double A,double B,double c){
		// a÷sin A == b ÷ sin B
		return c/Math.sin(Math.toRadians(A))*Math.sin(Math.toRadians(B));
	}

	/**
	 * 获取对边
	 * @param a 边长
	 * @param b 边长
	 * @param degree 角度
	 * @return
	 */
	public static Double getLengthOfSide(double a,double b,double degree){
		System.out.println(String.format("a:%s,b:%s,degrees:%s",a,b,degree));
		return Math.sqrt(b*b+a*a-2*a*b*Math.cos(Math.toRadians(degree)));
	}

	/**
	 * 已知边长  求AC 角度
	 * @param a
	 * @param b
	 * @param c
	 * @return
	 */
	public static double getDegree(double a, double b, double c){
		// 计算弧度表示的角
		double degrees = Math.acos((a*a + b * b - c * c) / (2.0 * a * b));
		// 用角度表示的角
		return Math.toDegrees(degrees);
	}

	/**
	 *  根据三角函数  已知角度和点（距离）,求垂直高度
	 * @return
	 */
	public static double getVerticalLength(double angle, double bevel){
		//角度
//		double angle=45.0;
		//斜边长
		BigDecimal c = BigDecimal.valueOf(bevel);
		//转换为弧度制
		double radians = Math.toRadians(angle);
		//正弦值
		BigDecimal sin = BigDecimal.valueOf(Math.sin(radians));
		//四舍五入保留2位 小数
		sin = sin.setScale(4, BigDecimal.ROUND_HALF_UP);
		//垂直高度  a边长
		BigDecimal a = c.multiply(sin);
		//余弦值
//		BigDecimal cos=BigDecimal.valueOf(Math.cos(radians));
//		//四舍五入保留2位小数
//		cos = cos.setScale(2, BigDecimal.ROUND_HALF_UP);
//		//水平长度  b边长
//		BigDecimal b = c.multiply(cos);
//		System.out.println("sin="+sin+" cos="+cos);
//		System.out.println("a="+a+" b="+b);
		return a.doubleValue();
	}




//	public static double getLastBevel(double xie_bian,double bevel){
//		double height = 0d;
//
//		double height_2 =  (xie_bian * xie_bian) - (bevel * bevel);
//		height = height
//
//
//		return  height;
//	}


	public static int getAngleByHeightAndAngle(double height,double radius){
		int aa = getDegree(0, 0, height, radius, height, 0);
		return aa;
	}

	/**
	 *
	 * @param vertexPointX -- 角度对应顶点X坐标值
	 * @param vertexPointY -- 角度对应顶点Y坐标值
	 * @param point0X
	 * @param point0Y
	 * @param point1X
	 * @param point1Y
	 * @return
	 */
	private static int getDegree(double vertexPointX, double vertexPointY, double point0X, double point0Y, double point1X, double point1Y) {
		//向量的点乘
		double vector = (point0X - vertexPointX) * (point1X - vertexPointX) + (point0Y - vertexPointY) * (point1Y - vertexPointY);
		//向量的模乘
		double sqrt = Math.sqrt(
				(Math.abs((point0X - vertexPointX) * (point0X - vertexPointX)) + Math.abs((point0Y - vertexPointY) * (point0Y - vertexPointY)))
						* (Math.abs((point1X - vertexPointX) * (point1X - vertexPointX)) + Math.abs((point1Y - vertexPointY) * (point1Y - vertexPointY)))
		);
		//反余弦计算弧度
		double radian = Math.acos(vector / sqrt);
		//弧度转角度制
		return (int) (180 * radian / Math.PI);
	}

	private  static int getIn_angle(int x1, int x2, int y1, int y2, int z1, int z2) {
         /*
          *^y
          *|
           |         /| y点
           |        / |
           |       /  |
          0|--- x点----z点---------->x
           |
          */

		//向量的点乘
		int t =(y1-x1)*(z1-x1)+(y2-x2)*(z2-x2);

		//为了精确直接使用而不使用中间变量
		//包含了步骤：A=向量的点乘/向量的模相乘
		//          B=arccos(A)，用反余弦求出弧度
		//          result=180*B/π 弧度转角度制
		int result =(int)(180 * Math.acos(
				t/Math.sqrt
						((Math.abs((y1-x1)*(y1-x1))+Math.abs((y2-x2)*(y2-x2)))
								*(Math.abs((z1-x1)*(z1-x1))+Math.abs((z2-x2)*(z2-x2)))
						))
				/Math.PI);
		//      pi   = 180
		//      x    =  ？
		//====> ?=180*x/pi

		return result;
	}


	public static double angleBetween2Lines(Line2D line1, Line2D line2) {
		double slope1 = line1.getY1() - line1.getY2() / line1.getX1() - line1.getX2();
		double slope2 = line2.getY1() - line2.getY2() / line2.getX1() - line2.getX2();
		double angle = Math.atan((slope1 - slope2) / (1 - (slope1 * slope2)));
		return angle;
	}

	/**
	 *  已知2个直角边，求夹角
	 * @param a
	 * @param b
	 * @return
	 */
	public static double getAngleByBevel(Double a, Double b){
		double aaa = Math.atan(a / b) * 180 / Math.PI;
		return aaa;
	}


	/**
	 * 根据圆锥的高度和角度 来计算 体积
	 * @param deviceRange   设备参数
	 * @param cone_height   椎体总高度
	 * @return
	 */
	public static double getConeVolumeByHeight(DeviceRange deviceRange, double cone_height){
		double xiebian = 0;
		//store_radius   筒仓半径
		double store_radius = deviceRange.getStoreDiameter() / 2;
		//下椎体的总斜边长
		double coneXieBian2 = deviceRange.getConeHeight() * deviceRange.getConeHeight() + store_radius* store_radius;
		double coneXiebianTotal = Math.pow(coneXieBian2, 2);

		//height  空余的平均高度
		double height = deviceRange.getConeHeight();
		double x0 = cone_height;
		double c0 = store_radius;

		double c1 = ( x0 / height) * coneXiebianTotal;

//		double x1 = store_radius;
//		// 直接三角形 等比公式
//		double c1 = (x1 / x0) * c0;
		xiebian = c1;
		System.out.println("下锥计算的斜边长：" + xiebian);

		double radius = getRightSideFromLength(cone_height,xiebian);
		System.out.println("下锥计算的半径：" + radius);
		Cone cone = new Cone();
		cone.setIsEllipse(deviceRange.getIsEllipse());
		cone.setShortHalf(deviceRange.getShortHalfShaft());
		cone.setLongHalf(deviceRange.getLongHalfShaft());
		cone.setRad(radius);
		cone.setHeight(height);
		return cone.volume();
	}

	/**
	 *  根据圆锥的高度和角度 来计算 体积
	 * @param height
	 * @param angle
	 * @return
	 */
	public static double getConeVolumeByHeightAndAngle(double height,double angle){
		double xiebian = getHypotenuseFromDegree(angle, height);
		double radius = getRightSideFromLength(height,xiebian);
		Cone cone = new Cone();
		cone.setRad(radius);
		cone.setHeight(height);
		return cone.volume();
	}


	public static void main(String[] args) {


//		斜边c=Math.sqrt(Math.pow(a,2)+Math.pow(b,2))
//
//		角1=Math.atan(b/a)*180/Math.PI 或者 90-角2
//		角2=Math.asin(a/c)*180/Math.PI 或者 90-角1

//		double aaa = Math.atan(0.7 / 0.975) * 180 / Math.PI;
//		System.out.println("aaa: " + aaa);
//
//
//		double height = MathUtil.getVerticalLength(38, 118);
//		System.out.println("height:" + height);
//
//		double dd = getVerticalLength(5,10);
//
//		System.out.println("垂直高度===: " + dd);
//
//		System.out.println("求第三边长：" + hypotenuse(5,5));
//
//
//		double aaa = getAngleByBevel(1d,13d);
//		System.out.println("aa=" + aaa);
//
//
//		System.out.println("30°对应的弧度是：" + Math.toRadians(30));
//		System.out.println("&#34;π/6对应的角度是：" + Math.toDegrees(Math.PI / 6));
//		System.out.println("45°对应的弧度是："+ Math.toRadians(45));
//		System.out.println(";π/4对应的角度是：" + Math.toDegrees(Math.PI / 4));
//
//
//		int aa = getDegree(0, 0, 10, 5, 10, 0);
//		System.out.println("aa:" + aa);
//
//		int bb = getAngleByHeightAndAngle(10,5);
//		System.out.println("bb:" + bb);
//
//
//		double d = 5 / Math.tan(60);// getDi(5,60);
//
//
//		//斜边长
//		System.out.println("getHypotenuseFromDegree:" + getHypotenuseFromDegree(30, 5));
//
//
//		System.out.println("getRightSideFromLength(5,5.773502691896257);" + getRightSideFromLength(5,5.773502691896257));
//
//
//		System.out.println("Math.tan(30):" + Math.tan(30));
//		System.out.println("底部长度： " + d);
//
////		double angle = Math.atan(10) / 5;
////		System.out.println("angle: " + angle);
//
////		int x1 = 0,x2 = 0;
////		int y1 = 10,y2 = 5;
////		int z1 = 10, z2 = 0;
////
////
////		int result = getIn_angle(x1, x2, y1, y2, z1, z2);
////		System.out.println("夹角为："+result+"度");
//
//         /*
//          *^y
//          *|
//           |         /| y点
//           |        / |
//           |       /  |
//          0|--- x点----z点---------->x
//           |
//          */
//		int x1 = 255;
//		int x2=145;
//		//中间点的坐标x(x1,x2)
//		int y1=211;
//		int y2=147;
//		//y点(y1,y2)
//		int z1=271;
//		int z2=182;
//		//z点(z1,z2)
//		int result = getIn_angle(x1, x2, y1, y2, z1, z2);
//		System.out.println("夹角为："+result+"度");
//



//		double d1 = 10.12;
//		double d2 = 11.123;
//		double d = getDoubleByInt(123,57);
//		double d3 = getDoubleByD(d1,d2);
//		System.out.println(d3);
//
//
//		int aa = ((180 * 10) / 12) * 60;
//		System.out.println("aa:" + aa);

		BigDecimal b1 = new BigDecimal(500000000);
		BigDecimal b2 = new BigDecimal(0.000000000005);

		BigDecimal bPlus = b1.add(b2);
		System.out.println("b1 + b2  = " + bPlus);

		BigDecimal bPlus1 = b2.add(b1);
		System.out.println("b2 + b1  = " + bPlus1);
//
		BigDecimal bDivide = b2.divide(b1,15, RoundingMode.HALF_UP);
		System.out.println("b1 / b2  = " + bDivide);
//
//		double bb1 = 500000000d;
//
//		double bb2 = 0.000000000005d;
//
//		double bbPlus = bb1 + bb2;
//		System.out.println("bb1 + bb2  = " + bbPlus);
//
//		double bbPlus1 = bb2 + bb1;
//		System.out.println("bb2 + bb1  = " + bbPlus1);


//		double[] doubles = { 5000d, 0.05d,0.00005d, 148d,0.000000000005d };
//		Arrays.sort(doubles);
//		double[] doubles1 = doubles;
//
//		System.out.println();

// 创建BigDecimal数组
//		BigDecimal[] bigDecimals = {
//				new BigDecimal(5000),
//				new BigDecimal(0.05),
//				new BigDecimal(0.00005),
//				new BigDecimal(148),
//				new BigDecimal(0.000000000005),
//		};
//
//		// 从小到大排序
//		Arrays.sort(bigDecimals);
//
//		// 输出排序后的数组
//		System.out.println(Arrays.toString(bigDecimals));
//


//
//		BigDecimal b3 = new BigDecimal(500000000);
//		BigDecimal b4 = new BigDecimal(0.000000000005);
//		// 除法
//		BigDecimal quotient = b3.divide(b4);
//		System.out.println("b1 / b2  = " +quotient);


	}

	public static double[] bubbleSort(double[] arr) {
		int n = arr.length;
		for (int i = 0; i < n - 1; i++) {
			for (int j = 0; j < n - i - 1; j++) {
				if (arr[j] > arr[j + 1]) {
					// 交换 arr[j+1] 和 arr[j]
					double temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
		return arr;
	}


}
